package com.nbsaas.boot.lock.impl;

import com.nbsaas.boot.lock.api.LockService;

import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockServiceImpl implements LockService {

    private final ConcurrentMap<String, Lock> lockMap = new ConcurrentHashMap<>();
    private final LockFactory lockFactory;

    // 构造函数，接受一个锁工厂来创建锁
    public LockServiceImpl(LockFactory lockFactory) {
        this.lockFactory = lockFactory;
    }

    @Override
    public boolean lock(String key) {
        Lock lock = lockMap.get(key);
        if (lock != null) {
            // 锁已存在，直接尝试获取锁
            return lock.tryLock();
        }

        // 锁不存在时创建新的锁并尝试获取
        lock = lockFactory.createLock();
        Lock existingLock = lockMap.putIfAbsent(key, lock);
        if (existingLock != null) {
            // 如果插入时锁已被创建，直接尝试获取锁
            return existingLock.tryLock();
        }

        // 成功插入新锁，尝试获取
        return lock.tryLock();
    }

    @Override
    public boolean lock(String key, long timeout, TimeUnit unit) {
        Lock lock = lockMap.get(key);
        if (lock != null) {
            // 锁已存在，尝试获取锁，带有超时限制
            try {
                return lock.tryLock(timeout, unit);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }

        // 锁不存在时创建新的锁并尝试获取
        lock = lockFactory.createLock();
        Lock existingLock = lockMap.putIfAbsent(key, lock);
        if (existingLock != null) {
            // 插入时锁已存在，直接尝试获取锁
            try {
                return existingLock.tryLock(timeout, unit);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
        // 插入新锁后尝试获取
        try {
            return lock.tryLock(timeout, unit);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }

    @Override
    public boolean unlock(String key) {
        Lock lock = lockMap.get(key);
        if (lock != null) {
            lock.unlock();  // 释放锁
            lockMap.remove(key);  // 解锁后移除锁
            return true;
        }
        return false;
    }

    @Override
    public boolean isLocked(String key) {
        Lock lock = lockMap.get(key);
        if (lock instanceof ReentrantLock) {
            return ((ReentrantLock) lock).isLocked();
        }
        return false;
    }
}
